package container

type Set[V comparable] struct {
	elements map[V]struct{}
}

// 创建一个Set
func NewSet[V comparable]() *Set[V] {
	return &Set[V]{elements: make(map[V]struct{})}
}

// 添加元素
func (s *Set[V]) Add(element V) {
	s.elements[element] = struct{}{}
}

// 添加成功返回true,如果已经存在,则返回false
func (s *Set[V]) AddIfNotExist(element V) bool {
	if _, ok := s.elements[element]; ok {
		return false
	}
	s.elements[element] = struct{}{}
	return true
}

// 删除元素, 基本类型和字符串好使,如果存储的是对象和指针,那么除非能传递相同的指针,否则无法删除,那么就可以使用RemoveByField
func (s *Set[V]) Remove(element V) {
	delete(s.elements, element)
}

// 根据内部对象字段删除, 遍历删除
func (s *Set[V]) RemoveByField(fun func(element V) bool) {
	for element := range s.elements {
		if fun(element) {
			delete(s.elements, element)
		}
	}
}

// 根据内部对象字段查询, 遍历查询
func (s *Set[V]) FindByField(fun func(element V) bool) V {
	for element := range s.elements {
		if fun(element) {
			return element
		}
	}
	var v V
	return v
}

// 是否包含元素
func (s *Set[V]) Contains(element V) bool {
	_, ok := s.elements[element]
	return ok
}

// 获取Set长度
func (s *Set[V]) Len() int {
	return len(s.elements)
}

// 获取Set所有元素
func (s *Set[V]) Elements() []V {
	var elements []V
	for element := range s.elements {
		elements = append(elements, element)
	}
	return elements
}

// 清空Set
func (s *Set[V]) Clear() {
	s.elements = make(map[V]struct{})
}

// 是否为空
func (s *Set[V]) IsEmpty() bool {
	return len(s.elements) == 0
}

// 遍历Set
func (s *Set[V]) Range(f func(element V) bool) {
	for element := range s.elements {
		if !f(element) {
			break
		}
	}
}

// 转换为切片
func (s *Set[V]) ToSlice() []V {
	var slice []V
	for k := range s.elements {
		slice = append(slice, k)
	}
	return slice
}

// 取第一个
func (s *Set[V]) First() V {
	for k := range s.elements {
		return k
	}
	var v V
	return v
}
